<?php

/**
 * Abstract gateway utilizing Zend_Db_Table.
 *
 * @author    Mon Zafra <monzee at gmail>
 * @copyright (c)2009 Mon Zafra
 * @license   http://monzee.wordpress.com/license New BSD
 * @version   $Id: Zdt.php 38 2009-02-18 17:12:39Z monzee $
 */
abstract class Admin_Gateway_Zdt extends Zend_Db_Table_Abstract
{
    /**
     * Generates a WHERE condition to be used with fetchRow() or fetchAll()
     *
     * @param mixed      $column   Column name or array of column names. If
     *                             $criteria is null, the string is treated as
     *                             a Zend_Db_Expr.
     * @param mixed|null $criteria A value, an array of values, or an array of
     *                             array of values if $column is an array. In
     *                             latter, if the number of elements does not
     *                             match the number of $columns, the unmatched
     *                             $columns will be treated as a Zend_Db_Expr.
     * @return Zend_Db_Table_Select
     */
    public function fetchBy($column, $criteria = null)
    {
        $adapter = $this->getAdapter();

        $sel = $this->select();

        if (is_array($column)) {
            $criteria = (array)$criteria;
            $value = reset($criteria);
            foreach ($column as $col) {
                if (false === $value) {
                    $sel = $sel->where(new Zend_Db_Expr($col));
                } else {
                    $where = $adapter->quoteIdentifier($col);
                    $sel = $this->_addWhere($sel, $where, $value);
                    $value = next($criteria);
                }
            }
        } else {
            if (null === $criteria) {
                $sel = $sel->where(new Zend_Db_Expr($column));
            } else {
                $where = $adapter->quoteIdentifier($column);
                $sel = $this->_addWhere($sel, $where, $criteria);
            }
        }

        return $sel;
    }

    /**
     * Adds a WHERE = ? or WHERE IN (?) if $value is an array
     *
     * @param Zend_Db_Table_Select $select
     * @param mixed $where
     * @param mixed $value
     * @return Zend_Db_Table_Select
     */
    protected function _addWhere($select, $where, $value)
    {
        if (is_array($value)) {
            return $select->where($where . ' IN (?)', $value);
        } else {
            return $select->where($where . ' = ?', $value);
        }
    }

    /**
     * Overridden to remove Zend_Loader::loadClass(). It won't work with the
     * module autloader otherwise
     *
     * Fetches one row in an object of type Zend_Db_Table_Row_Abstract,
     * or returns null if no row matches the specified criteria.
     *
     * @param string|array|Zend_Db_Table_Select $where  OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object.
     * @param string|array                      $order  OPTIONAL An SQL ORDER clause.
     * @return Zend_Db_Table_Row_Abstract|null The row results per the
     *     Zend_Db_Adapter fetch mode, or null if no row found.
     */
    public function fetchRow($where = null, $order = null)
    {
        if (!($where instanceof Zend_Db_Table_Select)) {
            $select = $this->select();

            if ($where !== null) {
                $this->_where($select, $where);
            }

            if ($order !== null) {
                $this->_order($select, $order);
            }

            $select->limit(1);

        } else {
            $select = $where->limit(1);
        }

        $rows = $this->_fetch($select);

        if (count($rows) == 0) {
            return null;
        }

        $data = array(
            'table'   => $this,
            'data'     => $rows[0],
            'readOnly' => $select->isReadOnly(),
            'stored'  => true
        );

        return new $this->_rowClass($data);
    }

    /**
     * Overridden to remove Zend_Loader::loadClass(). It won't work with the
     * module autloader otherwise
     *
     * Fetches all rows.
     *
     * Honors the Zend_Db_Adapter fetch mode.
     *
     * @param string|array|Zend_Db_Table_Select $where  OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object.
     * @param string|array                      $order  OPTIONAL An SQL ORDER clause.
     * @param int                               $count  OPTIONAL An SQL LIMIT count.
     * @param int                               $offset OPTIONAL An SQL LIMIT offset.
     * @return Zend_Db_Table_Rowset_Abstract The row results per the Zend_Db_Adapter fetch mode.
     */
    public function fetchAll($where = null, $order = null, $count = null, $offset = null)
    {
        if (!($where instanceof Zend_Db_Table_Select)) {
            $select = $this->select();

            if ($where !== null) {
                $this->_where($select, $where);
            }

            if ($order !== null) {
                $this->_order($select, $order);
            }

            if ($count !== null || $offset !== null) {
                $select->limit($count, $offset);
            }

        } else {
            $select = $where;
        }

        $rows = $this->_fetch($select);

        $data  = array(
            'table'    => $this,
            'data'     => $rows,
            'readOnly' => $select->isReadOnly(),
            'rowClass' => $this->_rowClass,
            'stored'   => true
        );

        return new $this->_rowsetClass($data);
    }

}
